﻿#region License
/*
Copyright (c) 2009, G.W. van der Vegt
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided 
that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this list of conditions and the 
  following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and 
  the following disclaimer in the documentation and/or other materials provided with the distribution.

* Neither the name of G.W. van der Vegt nor the names of its contributors may be 
  used to endorse or promote products derived from this software without specific prior written 
  permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
*/
#endregion License

namespace Swiss
{
    using System;
    using System.Runtime.InteropServices.ComTypes;
    using System.Runtime.InteropServices;

    /// <summary>
    /// 
    /// </summary>
    public class Interop
    {
        /// <summary>
        /// The different types of entities inside a compound document.
        /// </summary> 
        public enum StorageType
        {
            /// <summary>
            /// 
            /// </summary>
            stStorage = 0x01,

            /// <summary>
            /// 
            /// </summary>
            stStream = 0x02,

            /// <summary>
            /// 
            /// </summary>
            stLockBytes = 0x03,

            /// <summary>
            /// 
            /// </summary>
            stProperties = 0x04
        }

        /// <summary>
        /// The different starting points for Seek operations.
        /// </summary>
        public enum STREAM_SEEK
        {
            /// <summary>
            /// Relative to Start.
            /// </summary>
            SET = 0x0,

            /// <summary>
            /// Relative to Current.
            /// </summary>
            CUR = 0x1,

            /// <summary>
            /// Relative to End.
            /// </summary>
            END = 0x2
        }

        /// <summary>
        /// Storage Modes.
        /// </summary>
        [Flags]
        public enum STGM
        {
            /// <summary>
            /// 
            /// </summary>
            DIRECT = 0x00000000,

            /// <summary>
            /// 
            /// </summary>
            TRANSACTED = 0x00010000,

            /// <summary>
            /// 
            /// </summary>
            SIMPLE = 0x08000000,

            /// <summary>
            /// 
            /// </summary>
            READ = 0x00000000,

            /// <summary>
            /// 
            /// </summary>
            WRITE = 0x00000001,

            /// <summary>
            /// 
            /// </summary>
            READWRITE = 0x00000002,

            /// <summary>
            /// 
            /// </summary>
            SHARE_DENY_NONE = 0x00000040,

            /// <summary>
            /// 
            /// </summary>
            SHARE_DENY_READ = 0x00000030,

            /// <summary>
            /// 
            /// </summary>
            SHARE_DENY_WRITE = 0x00000020,

            /// <summary>
            /// 
            /// </summary>
            SHARE_EXCLUSIVE = 0x00000010,

            /// <summary>
            /// 
            /// </summary>
            PRIORITY = 0x00040000,

            /// <summary>
            /// 
            /// </summary>
            DELETEONRELEASE = 0x04000000,

            /// <summary>
            /// 
            /// </summary>
            NOSCRATCH = 0x00100000,

            /// <summary>
            /// 
            /// </summary>
            CREATE = 0x00001000,

            /// <summary>
            /// 
            /// </summary>
            CONVERT = 0x00020000,

            /// <summary>
            /// 
            /// </summary>
            FAILIFTHERE = 0x00000000,

            /// <summary>
            /// 
            /// </summary>
            NOSNAPSHOT = 0x00200000,

            /// <summary>
            /// 
            /// </summary>
            DIRECT_SWMR = 0x00400000,
        }

        /// <summary>
        /// Storage Types.
        /// </summary>
        [Flags]
        public enum STGTY
        {
            /// <summary>
            /// Storage (Directory).
            /// </summary>
            STORAGE = 1,

            /// <summary>
            /// Stream (File).
            /// </summary>
            STREAM = 2,

            /// <summary>
            /// ?
            /// </summary>
            LOCKBYTES = 3,

            /// <summary>
            /// ?
            /// </summary>
            PROPERTY = 4
        }

        /// <summary>
        /// Storage Control.
        /// </summary>
        [Flags]
        public enum STGC
        {
            /// <summary>
            /// 
            /// </summary>
            DEFAULT = 0,

            /// <summary>
            /// 
            /// </summary>
            OVERWRITE = 1,

            /// <summary>
            /// 
            /// </summary>
            ONLYIFCURRENT = 2,

            /// <summary>
            /// 
            /// </summary>
            DANGEROUSLYCOMMITMERELYTODISKCACHE = 4,

            /// <summary>
            /// 
            /// </summary>
            CONSOLIDATE = 8
        }

        /// <summary>
        /// IEnumSTATSTG Interface.
        /// </summary>
        [ComImport]
        [Guid("0000000d-0000-0000-C000-000000000046")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IEnumSTATSTG
        {
            /// <summary>
            ///The user needs to allocate an STATSTG array whose size is celt. 
            /// </summary>
            /// <param name="celt"></param>
            /// <param name="rgelt"></param>
            /// <param name="pceltFetched"></param>
            /// <returns></returns>
            [PreserveSig]
            uint Next(uint celt, [MarshalAs(UnmanagedType.LPArray), Out] System.Runtime.InteropServices.ComTypes.STATSTG[] rgelt, out uint pceltFetched);

            /// <summary>
            /// 
            /// </summary>
            /// <param name="celt"></param>
            void Skip(uint celt);

            /// <summary>
            /// 
            /// </summary>
            void Reset();

            /// <summary>
            /// 
            /// </summary>
            /// <returns></returns>
            [return: MarshalAs(UnmanagedType.Interface)]
            IEnumSTATSTG Clone();
        }

        /// <summary>
        /// IStorage Interface.
        /// </summary>
        [ComImport]
        [Guid("0000000b-0000-0000-C000-000000000046")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IStorage
        {
            /// <summary>
            /// 
            /// </summary>
            /// <param name="pwcsName"></param>
            /// <param name="grfMode"></param>
            /// <param name="reserved1"></param>
            /// <param name="reserved2"></param>
            /// <param name="ppstm"></param>
            void CreateStream(
                /* [string][in] */ string pwcsName,
                /* [in] */ STGM grfMode,
                /* [in] */ uint reserved1,
                /* [in] */ uint reserved2,
                /* [out] */ out IStream ppstm);

            /// <summary>
            /// 
            /// </summary>
            /// <param name="pwcsName"></param>
            /// <param name="reserved1"></param>
            /// <param name="grfMode"></param>
            /// <param name="reserved2"></param>
            /// <param name="ppstm"></param>
            void OpenStream(
                /* [string][in] */ string pwcsName,
                /* [unique][in] */ IntPtr reserved1,
                /* [in] */ STGM grfMode,
                /* [in] */ uint reserved2,
                /* [out] */ out IStream ppstm);

            /// <summary>
            /// 
            /// </summary>
            /// <param name="pwcsName"></param>
            /// <param name="grfMode"></param>
            /// <param name="reserved1"></param>
            /// <param name="reserved2"></param>
            /// <param name="ppstg"></param>
            void CreateStorage(
                /* [string][in] */ string pwcsName,
                /* [in] */ STGM grfMode,
                /* [in] */ uint reserved1,
                /* [in] */ uint reserved2,
                /* [out] */ out IStorage ppstg);

            /// <summary>
            /// 
            /// </summary>
            /// <param name="pwcsName"></param>
            /// <param name="pstgPriority"></param>
            /// <param name="grfMode"></param>
            /// <param name="snbExclude"></param>
            /// <param name="reserved"></param>
            /// <param name="ppstg"></param>
            void OpenStorage(
                /* [string][unique][in] */ string pwcsName,
                /* [unique][in] */ IStorage pstgPriority,
                /* [in] */ STGM grfMode,
                /* [unique][in] */ IntPtr snbExclude,
                /* [in] */ uint reserved,
                /* [out] */ out IStorage ppstg);

            /// <summary>
            /// 
            /// </summary>
            /// <param name="ciidExclude"></param>
            /// <param name="rgiidExclude"></param>
            /// <param name="snbExclude"></param>
            /// <param name="pstgDest"></param>
            void CopyTo(
                /* [in] */ uint ciidExclude,
                /* [size_is][unique][in] */ Guid rgiidExclude, // should this be an array?
                /* [unique][in] */ IntPtr snbExclude,
                /* [unique][in] */ IStorage pstgDest);

            /// <summary>
            /// 
            /// </summary>
            /// <param name="pwcsName"></param>
            /// <param name="pstgDest"></param>
            /// <param name="pwcsNewName"></param>
            /// <param name="grfFlags"></param>
            void MoveElementTo(
                /* [string][in] */ string pwcsName,
                /* [unique][in] */ IStorage pstgDest,
                /* [string][in] */ string pwcsNewName,
                /* [in] */ uint grfFlags);

            /// <summary>
            /// 
            /// </summary>
            /// <param name="grfCommitFlags"></param>
            void Commit(
                /* [in] */ Int32 grfCommitFlags);

            /// <summary>
            /// 
            /// </summary>
            void Revert();

            /// <summary>
            /// 
            /// </summary>
            /// <param name="reserved1"></param>
            /// <param name="reserved2"></param>
            /// <param name="reserved3"></param>
            /// <param name="ppenum"></param>
            void EnumElements(
                /* [in] */ uint reserved1,
                /* [size_is][unique][in] */ IntPtr reserved2,
                /* [in] */ uint reserved3,
                /* [out] */ out IEnumSTATSTG ppenum);

            /// <summary>
            /// 
            /// </summary>
            /// <param name="pwcsName"></param>
            void DestroyElement(
                /* [string][in] */ string pwcsName);

            /// <summary>
            /// 
            /// </summary>
            /// <param name="pwcsOldName"></param>
            /// <param name="pwcsNewName"></param>
            void RenameElement(
                /* [string][in] */ string pwcsOldName,
                /* [string][in] */ string pwcsNewName);

            /// <summary>
            /// 
            /// </summary>
            /// <param name="pwcsName"></param>
            /// <param name="pctime"></param>
            /// <param name="patime"></param>
            /// <param name="pmtime"></param>
            void SetElementTimes(
                /* [string][unique][in] */ string pwcsName,
                /* [unique][in] */ System.Runtime.InteropServices.ComTypes.FILETIME pctime,
                /* [unique][in] */ System.Runtime.InteropServices.ComTypes.FILETIME patime,
                /* [unique][in] */ System.Runtime.InteropServices.ComTypes.FILETIME pmtime);

            /// <summary>
            /// 
            /// </summary>
            /// <param name="clsid"></param>
            void SetClass(
                /* [in] */ Guid clsid);

            /// <summary>
            /// 
            /// </summary>
            /// <param name="grfStateBits"></param>
            /// <param name="grfMask"></param>
            void SetStateBits(
                /* [in] */ uint grfStateBits,
                /* [in] */ uint grfMask);

            /// <summary>
            /// 
            /// </summary>
            /// <param name="pstatstg"></param>
            /// <param name="grfStatFlag"></param>
            void Stat(
                /* [out] */ out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg,
                /* [in] */ uint grfStatFlag);
        }

        /// <summary>
        /// Exception Codes.
        /// </summary>
        public enum STG
        {
            /// <summary>
            /// 
            /// </summary>
            CONVERT10_E_STG_FMT = (Int32)(0x800401C4 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            CONVERT10_E_STG_NO_STD_STREAM = (Int32)(0x800401C5 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            CONVERT10_E_STG_DIB_TO_BITMAP = (Int32)(0x800401C6 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_INVALIDFUNCTION = (Int32)(0x80030001 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_FILENOTFOUND = (Int32)(0x80030002 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_PATHNOTFOUND = (Int32)(0x80030003 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_TOOMANYOPENFILES = (Int32)(0x80030004 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_ACCESSDENIED = (Int32)(0x80030005 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_INVALIDHANDLE = (Int32)(0x80030006 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_INSUFFICIENTMEMORY = (Int32)(0x80030008 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_INVALIDPOINTER = (Int32)(0x80030009 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_NOMOREFILES = (Int32)(0x80030012 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_DISKISWRITEPROTECTED = (Int32)(0x80030013 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_SEEKERROR = (Int32)(0x80030019 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_WRITEFAULT = (Int32)(0x8003001D - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_READFAULT = (Int32)(0x8003001E - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_SHAREVIOLATION = (Int32)(0x80030020 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_LOCKVIOLATION = (Int32)(0x80030021 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_FILEALREADYEXISTS = (Int32)(0x80030050 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_INVALIDPARAMETER = (Int32)(0x80030057 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_MEDIUMFULL = (Int32)(0x80030070 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_PROPSETMISMATCHED = (Int32)(0x800300F0 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_ABNORMALAPIEXIT = (Int32)(0x800300FA - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_INVALIDHEADER = (Int32)(0x800300FB - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_INVALIDNAME = (Int32)(0x800300FC - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_UNKNOWN = (Int32)(0x800300FD - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_UNIMPLEMENTEDFUNCTION = (Int32)(0x800300FE - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_INVALIDFLAG = (Int32)(0x800300FF - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_INUSE = (Int32)(0x80030100 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_NOTCURRENT = (Int32)(0x80030101 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_REVERTED = (Int32)(0x80030102 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_CANTSAVE = (Int32)(0x80030103 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_OLDFORMAT = (Int32)(0x80030104 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_OLDDLL = (Int32)(0x80030105 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_SHAREREQUIRED = (Int32)(0x80030106 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_NOTFILEBASEDSTORAGE = (Int32)(0x80030107 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_EXTANTMARSHALLINGS = (Int32)(0x80030108 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_DOCFILECORRUPT = (Int32)(0x80030109 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_BADBASEADDRESS = (Int32)(0x80030110 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_DOCFILETOOLARGE = (Int32)(0x80030111 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_NOTSIMPLEFORMAT = (Int32)(0x80030112 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_INCOMPLETE = (Int32)(0x80030201 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_TERMINATED = (Int32)(0x80030202 - 0x100000000),

            /// <summary>
            /// Ole32 HResult Code for OK, no error.
            /// </summary>
            S_OK = 0x00000000,

            /// <summary>
            /// 
            /// </summary>
            S_CONVERTED = 0x00030200,

            /// <summary>
            /// 
            /// </summary>
            S_BLOCK = 0x00030201,

            /// <summary>
            /// 
            /// </summary>
            S_RETRYNOW = 0x00030202,

            /// <summary>
            /// 
            /// </summary>
            S_MONITORING = 0x00030203,

            /// <summary>
            /// 
            /// </summary>
            S_MULTIPLEOPENS = 0x00030204,

            /// <summary>
            /// 
            /// </summary>
            S_CONSOLIDATIONFAILED = 0x00030205,

            /// <summary>
            /// 
            /// </summary>
            S_CANNOTCONSOLIDATE = 0x00030206,

            /// <summary>
            /// 
            /// </summary>
            E_STATUS_COPY_PROTECTION_FAILURE = (Int32)(0x80030305 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_CSS_AUTHENTICATION_FAILURE = (Int32)(0x80030306 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_CSS_KEY_NOT_PRESENT = (Int32)(0x80030307 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_CSS_KEY_NOT_ESTABLISHED = (Int32)(0x80030308 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_CSS_SCRAMBLED_SECTOR = (Int32)(0x80030309 - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_CSS_REGION_MISMATCH = (Int32)(0x8003030A - 0x100000000),

            /// <summary>
            /// 
            /// </summary>
            E_RESETS_EXHAUSTED = (Int32)(0x8003030B - 0x100000000),
        }

        /// <summary>
        /// StgIsStorageFile Import.
        /// </summary>
        /// <param name="pwcsName"></param>
        /// <returns></returns>
        [DllImport("ole32.dll")]
        public static extern Int32 StgIsStorageFile(
            [MarshalAs(UnmanagedType.LPWStr)] string pwcsName);

        /// <summary>
        /// StgCreateDocfile Import.
        /// </summary>
        /// <param name="pwcsName"></param>
        /// <param name="grfMode"></param>
        /// <param name="reserved"></param>
        /// <param name="ppstgOpen"></param>
        /// <returns></returns>
        [DllImport("ole32.dll")]
        public static extern Int32 StgCreateDocfile(
            [MarshalAs(UnmanagedType.LPWStr)] string pwcsName,
            STGM grfMode,
            uint reserved,
            out IStorage ppstgOpen);

        /// <summary>
        /// StgOpenStorage import.
        /// </summary>
        /// <param name="pwcsName"></param>
        /// <param name="pstgPriority"></param>
        /// <param name="grfMode"></param>
        /// <param name="snbExclude"></param>
        /// <param name="reserved"></param>
        /// <param name="ppstgOpen"></param>
        /// <returns></returns>
        [DllImport("ole32.dll")]
        public static extern Int32 StgOpenStorage(
            [MarshalAs(UnmanagedType.LPWStr)] string pwcsName,
            IStorage pstgPriority,
            STGM grfMode,                // Access Method (uint)
            IntPtr snbExclude,           // Must be NULL
            uint reserved,               // Reserved
            out IStorage ppstgOpen);     // Returned Storage
    }
}
